using System.Buffers;
using System.Net;
using System.Net.Sockets;
using Nova.Net;

namespace KCP.Simple;

public class KcpSession : IKcpCallback
{
    public KcpServer Server;
    public UdpClient client;
    public IPEndPoint endPoint;
    public SimpleSegManager.Kcp kcp;

    public uint conv_mask;
    //状态：0新会话，1已确认
    public int state;
    public long lastTime; //最后更新的时间 

    public KcpSession()
    {
        LoopReceive();
    }
    
    public async void SendAsync(byte[] datagram, int offset, int length)
    {
        kcp.Send(datagram.AsSpan().Slice(offset, length));
    }

    public void Output(IMemoryOwner<byte> buffer, int avalidLength)
    {
        var s = buffer.Memory.Span.Slice(0, avalidLength).ToArray();
        client.SendAsync(s, s.Length, endPoint);
        buffer.Dispose();
    }
    
    public void RecvInput(byte[] data)
    {
        kcp.Input(data);
    }
    
    private async ValueTask<byte[]> ReceiveAsync()
    {
        Console.WriteLine("开始接收：ReceiveAsync");
        var (buffer, avalidLength) = kcp.TryRecv();
        while (buffer == null)
        {
            await Task.Delay(10);
            (buffer, avalidLength) = kcp.TryRecv();
        }
        var s = buffer.Memory.Span.Slice(0, avalidLength).ToArray();
        return s;
    }
    
    private void LoopReceive()
    {
        Console.WriteLine("LoopReceive");
        Task.Run(async () =>
        {
            while (true)
            {
                Console.WriteLine("LoopReceive await ReceiveAsync();");
                var res = await ReceiveAsync();
                ThreadPool.QueueUserWorkItem(state =>
                {
                    lock (Server)
                    {
                        Server.OnMessage.Invoke(this, res);
                    }
                });

            }
        });
    }
    
}